/**
 * @fileoverview Shared brief selection utilities
 * Reusable functions for selecting briefs interactively or via URL/ID
 */

import search from '@inquirer/search';
import type { AuthManager } from '@tm/core';
import { formatRelativeTime } from '@tm/core';
import chalk from 'chalk';
import ora, { type Ora } from 'ora';
import { getBriefStatusWithColor } from '../ui/formatters/status-formatters.js';
import * as ui from './ui.js';

export interface BriefSelectionResult {
	success: boolean;
	briefId?: string;
	briefName?: string;
	orgId?: string;
	orgName?: string;
	message?: string;
}

/**
 * Select a brief interactively using search
 */
export async function selectBriefInteractive(
	authManager: AuthManager,
	orgId: string
): Promise<BriefSelectionResult> {
	const spinner = ora('Fetching briefs...').start();

	try {
		// Fetch briefs from API
		const briefs = await authManager.getBriefs(orgId);
		spinner.stop();

		if (briefs.length === 0) {
			ui.displayWarning('No briefs available in this organization');
			return {
				success: false,
				message: 'No briefs available'
			};
		}

		// Prompt for selection with search
		const selectedBrief = await search<(typeof briefs)[0] | null>({
			message: 'Search for a brief:',
			pageSize: 15,
			source: async (input) => {
				const searchTerm = input?.toLowerCase() || '';

				// Static option for no brief
				const noBriefOption = {
					name: '(No brief - organization level)',
					value: null as any,
					description: 'Clear brief selection'
				};

				// Filter briefs based on search term
				const filteredBriefs = briefs.filter((brief) => {
					if (!searchTerm) return true;

					const title = brief.document?.title || '';
					const shortId = brief.id.slice(0, 8);
					const lastChars = brief.id.slice(-8);

					// Search by title, full UUID, first 8 chars, or last 8 chars
					return (
						title.toLowerCase().includes(searchTerm) ||
						brief.id.toLowerCase().includes(searchTerm) ||
						shortId.toLowerCase().includes(searchTerm) ||
						lastChars.toLowerCase().includes(searchTerm)
					);
				});

				// Group briefs by status
				const briefsByStatus = filteredBriefs.reduce(
					(acc, brief) => {
						const status = brief.status || 'unknown';
						if (!acc[status]) {
							acc[status] = [];
						}
						acc[status].push(brief);
						return acc;
					},
					{} as Record<string, typeof briefs>
				);

				// Define status order (most active first)
				const statusOrder = [
					'delivering',
					'aligned',
					'refining',
					'draft',
					'delivered',
					'done',
					'archived'
				];

				// Build grouped options
				const groupedOptions: any[] = [];

				for (const status of statusOrder) {
					const statusBriefs = briefsByStatus[status];
					if (!statusBriefs || statusBriefs.length === 0) continue;

					// Add status header as separator
					const statusHeader = getBriefStatusWithColor(status);
					groupedOptions.push({
						type: 'separator',
						separator: `\n${statusHeader}`
					});

					// Add briefs under this status
					statusBriefs.forEach((brief) => {
						const title =
							brief.document?.title || `Brief ${brief.id.slice(-8)}`;
						const shortId = brief.id.slice(-8);
						const description = brief.document?.description || '';
						const taskCountDisplay =
							brief.taskCount !== undefined && brief.taskCount > 0
								? chalk.gray(
										` (${brief.taskCount} ${brief.taskCount === 1 ? 'task' : 'tasks'})`
									)
								: '';

						const updatedAtDisplay = brief.updatedAt
							? chalk.gray(` • ${formatRelativeTime(brief.updatedAt)}`)
							: '';

						groupedOptions.push({
							name: `  ${title}${taskCountDisplay} ${chalk.gray(`(${shortId})`)}${updatedAtDisplay}`,
							value: brief,
							description: description
								? chalk.gray(`  ${description.slice(0, 80)}`)
								: undefined
						});
					});
				}

				// Handle any briefs with statuses not in our order
				const unorderedStatuses = Object.keys(briefsByStatus).filter(
					(s) => !statusOrder.includes(s)
				);
				for (const status of unorderedStatuses) {
					const statusBriefs = briefsByStatus[status];
					if (!statusBriefs || statusBriefs.length === 0) continue;

					const statusHeader = getBriefStatusWithColor(status);
					groupedOptions.push({
						type: 'separator',
						separator: `\n${statusHeader}`
					});

					statusBriefs.forEach((brief) => {
						const title =
							brief.document?.title || `Brief ${brief.id.slice(-8)}`;
						const shortId = brief.id.slice(-8);
						const description = brief.document?.description || '';
						const taskCountDisplay =
							brief.taskCount !== undefined && brief.taskCount > 0
								? chalk.gray(
										` (${brief.taskCount} ${brief.taskCount === 1 ? 'task' : 'tasks'})`
									)
								: '';

						const updatedAtDisplay = brief.updatedAt
							? chalk.gray(` • ${formatRelativeTime(brief.updatedAt)}`)
							: '';

						groupedOptions.push({
							name: `  ${title}${taskCountDisplay} ${chalk.gray(`(${shortId})`)}${updatedAtDisplay}`,
							value: brief,
							description: description
								? chalk.gray(`  ${description.slice(0, 80)}`)
								: undefined
						});
					});
				}

				return [noBriefOption, ...groupedOptions];
			}
		});

		if (selectedBrief) {
			// Update context with brief
			const briefName =
				selectedBrief.document?.title ||
				`Brief ${selectedBrief.id.slice(0, 8)}`;
			await authManager.updateContext({
				briefId: selectedBrief.id,
				briefName: briefName,
				briefStatus: selectedBrief.status,
				briefUpdatedAt: selectedBrief.updatedAt
			});

			ui.displaySuccess(`Selected brief: ${briefName}`);

			return {
				success: true,
				briefId: selectedBrief.id,
				briefName,
				message: `Selected brief: ${briefName}`
			};
		} else {
			// Clear brief selection
			await authManager.updateContext({
				briefId: undefined,
				briefName: undefined,
				briefStatus: undefined,
				briefUpdatedAt: undefined
			});

			ui.displaySuccess('Cleared brief selection (organization level)');

			return {
				success: true,
				message: 'Cleared brief selection'
			};
		}
	} catch (error) {
		spinner.fail('Failed to fetch briefs');
		throw error;
	}
}

/**
 * Select a brief from any input format (URL, ID, name) using tm-core
 * Presentation layer - handles display and context updates only
 *
 * All business logic (URL parsing, ID matching, name resolution) is in tm-core
 */
export async function selectBriefFromInput(
	authManager: AuthManager,
	input: string,
	tmCore: any
): Promise<BriefSelectionResult> {
	let spinner: Ora | undefined;
	try {
		spinner = ora('Resolving brief...');
		spinner.start();

		// Let tm-core handle ALL business logic:
		// - URL parsing
		// - ID extraction
		// - UUID matching (full or last 8 chars)
		// - Name matching
		const brief = await tmCore.tasks.resolveBrief(input);

		// Fetch org to get a friendly name and slug (optional)
		let orgName: string | undefined;
		let orgSlug: string | undefined;
		try {
			const org = await authManager.getOrganization(brief.accountId);
			orgName = org?.name;
			orgSlug = org?.slug;
		} catch {
			// Non-fatal if org lookup fails
		}

		// Update context: set org and brief
		const briefName = brief.document?.title || `Brief ${brief.id.slice(0, 8)}`;
		await authManager.updateContext({
			orgId: brief.accountId,
			orgName,
			orgSlug,
			briefId: brief.id,
			briefName,
			briefStatus: brief.status,
			briefUpdatedAt: brief.updatedAt
		});

		spinner.succeed('Context set from brief');
		console.log(
			chalk.gray(
				`  Organization: ${orgName || brief.accountId}\n  Brief: ${briefName}`
			)
		);

		return {
			success: true,
			briefId: brief.id,
			briefName,
			orgId: brief.accountId,
			orgName,
			message: 'Context set from brief'
		};
	} catch (error) {
		try {
			if (spinner?.isSpinning) spinner.stop();
		} catch {}
		throw error;
	}
}
